<?php

namespace App\Module;

use App\depository\PermissionsDep;
use App\depository\RoleHasPermissionsDep;
use App\depository\RolesDep;
use App\depository\TeamsDep;
use App\depository\UserDep;
use App\Enum\CommonEnum;
use App\Enum\PermissionsEnum;
use App\Enum\RolesEnum;
use App\Enum\UsersEnum;
use App\Mail\Forget;
use App\Mail\SendCode;
use App\Models\TokenModel;
use App\Models\User as UserModel;
use App\Service\DictService;
use App\depository\UserHasTeamsDep;
use App\Service\CodeService;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;

class UserModule extends BaseModule
{
    public function login($request)
    {
        $param = $request->input();

        $resUser = UserModel::where("name", $param['username'])->where("password", $param['password'])->where('is_del', CommonEnum::NO)->first();
        if (!$resUser) {
            return self::response([], '用户名或密码错误', 200);
        }

        if ($resUser->status == UsersEnum::STATUS_NO) {
            return self::response([], '该用户已被禁用', 200);
        }

        $token = $resUser->createToken('gonghui_pc_token')->plainTextToken;
        $detail = [
            'id' => $resUser->id,
            'is_admin' => $resUser->is_admin
        ];
        return self::response(['token' => $token, 'detail' => $detail]);
    }

    public function list($request)
    {

        $param = $request->input();

        $param['per_page'] = $param['per_page'] ?? 10;
        $param['current_page'] = $param['current_page'] ?? 1;

        $roleDep = new RolesDep();
        $dep = new UserDep();
        $userHasTeams = new UserHasTeamsDep();

        $resList = $dep->list($param);

        $list = $resList->getCollection()->toBase();
        $data['list'] = $list->map(function ($item) use ($roleDep, $userHasTeams) {
            $resRole = $roleDep->firstByRoleId($item->role_id);
            $resTeams = $userHasTeams->getByUserId($item->id);
            return [
                "id" => $item->id,
                "username" => $item->name,
                "password" => $item->password,
                "nickname" => $item->nickname,
                "role" => $resRole ? $resRole->name : CommonEnum::DEFAULT_NULL,
                "role_id" => $item->role_id,
                "email" => $item->email,
                "status" => $item->status,
                'team_id' => $resTeams->pluck('team_id'),
                "status_show" => UsersEnum::$statusArr[$item->status] ?? CommonEnum::DEFAULT_NULL,
                "created_at" => $item->created_at->toDateTimeString()
            ];
        });

        $data['page'] = [
            'per_page' => $param['per_page'],
            'current_page' => $param['current_page'],
            'total_page' => $resList->lastPage(),
            'total' => $resList->total(),
        ];

        return self::response($data);
    }

    public function init()
    {

        $dictService = new DictService();
        $dictService->setRoles()->setUserStatus()->setTeams();

        $data['dict'] = $dictService->getDict();

        return self::response($data);
    }

    public function add($request)
    {

        $param = $request->input();
        $userDep = new UserDep();

        $resFind = $userDep->firstByUsername($param['username']);
        if ($resFind) {
            return self::response([], "账号已存在，请勿重复添加", 200);
        }

        $data = [
            'username' => $param['username'],
            'integral' => $param['integral'],
            'expire_at' => $param['expire_at'],
        ];

        $userDep->add($data);
        return self::response();
    }

    public function del($request)
    {

        $param = $request->input();
        $userDep = new UserDep();

        $userDep->del($param['id']);
        return self::response();
    }

    public function edit($request)
    {

        $param = $request->input();
        $userDep = new UserDep();
        $userHasTeamsDep = new UserHasTeamsDep();

        if (empty($param['username']) || empty($param['password']) || empty($param['nickname']) || empty($param['role_id'])) {
            return self::response([], '必填项不可以为空', 100);
        }

        $resFind = $userDep->firstByUsername($param['username']);
        if ($resFind && $resFind->id !== $param['id']) {
            return self::response([], "账号已存在，请勿重复添加", 200);
        }

        $resDetail = $userDep->firstById($param['id']);

        $data = [
            'name' => $param['username'],
            'password' => $param['password'],
            'nickname' => $param['nickname'],
            'role_id' => $param['role_id'],
            'status' => $param['status']
        ];
        $userHasTeamsDep->delByUserId($param['id']);
        $userDep->upd($param['id'], $data);

        if (!empty($param['team_id'])) {
            foreach ($param['team_id'] as $teamId) {
                $data = [
                    'team_id' => $teamId,
                    'user_id' => $param['id']
                ];
                $userHasTeamsDep->add($data);
            }
        }

        if ($param['status'] == UsersEnum::STATUS_NO || $resDetail->password != $param['password']) {
            TokenModel::where('tokenable_id', $param['id'])->delete();
        }
        return self::response();
    }

    public function check($request)
    {

        $param = $request->input();

        if (empty($param['username']) || empty($param['type'])) {
            return self::response([], "参数错误", 100);
        }

        if ($param['type'] === 1 && empty($param['integral'])) {
            return self::response([], "参数错误", 100);
        }

        $userDep = new UserDep();
        $resUser = $userDep->firstByUsername($param['username']);
        if (!$resUser) {
            return self::response([], "账号不存在", 200);
        }

        //积分
        if ($param['type'] === 1) {
            if ($resUser->integral < $param['integral']) {
                return self::response([], "积分不足", 300);
            }
            $newIntegral = $resUser->integral - $param['integral'];
            $data = [
                'integral' => $newIntegral
            ];
            $userDep->upd($resUser->id, $data);
            return self::response(['integral' => $newIntegral]);
        } else {
            if ($resUser->expire_at < date("Y-m-d H:i:s")) {
                return self::response([], "已到期", 400);
            }
            $data = [
                'expire_at' => $resUser->expire_at
            ];
            return self::response($data);
        }
    }

    public function detail($request)
    {

        $param = $request->input();

        $userId = $request->user()->id;
        $userDep = new UserDep();
        $resDetail = $userDep->firstById($userId);

        $data['detail'] = [
            'id' => $resDetail->id,
            'username' => $resDetail->name,
            'password' => $resDetail->password,
            'email' => $resDetail->email,
            'nickname' => $resDetail->nickname,
        ];

        return self::response($data);
    }

    public function sendCode($request)
    {

        $param = $request->input();

        $codeService = new CodeService($request->session());

        $code = $codeService->setCode();

        try {
            Mail::to($param['email'])->send(new SendCode($code));
        } catch (\Exception $err) {
            return self::response([], '邮件发送失败，请检查邮箱是否正确', 200);
        }

        return self::response();
    }

    public function register($request)
    {

        $param = $request->input();

        $userDep = new UserDep();


        if (empty($param['username'])) {
            return self::response([], '请输入用户名', 100);
        }

        $resUser = $userDep->firstByUsername($param['username']);
        if ($resUser) {
            return self::response([], '用户名已被占用，请重新输入', 100);
        }


        if (empty($param['nickname'])) {
            return self::response([], '请输入昵称', 100);
        }

        if (empty($param['email'])) {
            return self::response([], '请输入邮箱', 100);
        }

        if (empty($param['code'])) {
            return self::response([], '请输入验证码', 100);
        }

        $codeService = new CodeService($request->session());
        $resCheckCode = $codeService->checkCode($param['code']);
        if (!$resCheckCode['success']) {
            return self::response([], $resCheckCode['msg'], 100);
        }

        if (empty($param['password'])) {
            return self::response([], '请输入密码', 100);
        }

        if (empty($param['confirm_password'])) {
            return self::response([], '请输入确认密码', 100);
        }

        if ($param['password'] != $param['confirm_password']) {
            return self::response([], '两次密码输入不一致', 100);
        }

        //        $roleDep = new RolesDep();
        //        $resRole = $roleDep->firstByGuardName(RolesEnum::ROLE_CUSTOMER);
        //        if (!$resRole) {
        //            return self::response([], '请联系管理员添加默认访客角色', 200);
        //        }

        $data = [
            'name' => $param['username'],
            'nickname' => $param['nickname'],
            'email' => $param['email'],
            'email_verified_at' => date('Y-m-d H:i:s'),
            //            'role_id' => '',
            'password' => $param['password'],
            'status' => UsersEnum::STATUS_YES
        ];


        $userDep->add($data);

        return self::response();
    }


    public function changeProfile($request)
    {

        $param = $request->input();

        $userDep = new UserDep();
        $resUser = $userDep->firstById($request->user()->id);

        if (empty($param['nickname'])) {
            return self::response([], '请输入昵称', 100);
        }

        if (empty($param['email'])) {
            return self::response([], '请输入邮箱', 100);
        }

        if ($param['email'] != $resUser->email) {
            if (empty($param['code'])) {
                return self::response([], '请输入邮箱验证码', 100);
            }
            $codeService = new CodeService($request->session());
            $resCheckCode = $codeService->checkCode($param['code']);
            if (!$resCheckCode['success']) {
                return self::response([], $resCheckCode['msg'], 100);
            }
        }

        if (empty($param['password'])) {
            return self::response([], '请输入密码', 100);
        }

        if ($resUser->password != $param['password']) {
            TokenModel::where('tokenable_id', $param['id'])->delete();
        }

        $data = [
            'name' => $param['username'],
            'nickname' => $param['nickname'],
            'email' => $param['email'],
            'email_verified_at' => date('Y-m-d H:i:s'),
            'password' => $param['password'],
        ];

        $userDep->upd($param['id'], $data);

        return self::response();
    }

    public function permissions($request)
    {

        $param = $request->input();

        $user = $request->user();
        $userId = $user->id;

        $userDep = new UserDep();
        $roleHasPermissionsDep = new RoleHasPermissionsDep();
        $permissionsDep = new PermissionsDep();


        $data['user'] = ['is_admin' => $user->is_admin];

        $resUser = $userDep->firstById($userId);
        if ($resUser->is_admin == CommonEnum::YES) {
            $allPermissions = $permissionsDep->normal();
            $menuPermissions = $allPermissions->filter(function ($item) {
                return $item->type == PermissionsEnum::TYPE_MENU;
            });
            $buttonPermissions = $allPermissions->filter(function ($item) {
                return $item->type == PermissionsEnum::TYPE_BUTTON;
            });

            $data['keys'] = $menuPermissions->map(function ($item) {
                return $item->guard_name;
            })->values();

            $allPermissions->filter(function ($item) use ($buttonPermissions, &$data) {
                $buttonPermissions->each(function ($item1) use ($item, &$data) {
                    if ($item1->parent_id == $item->id) {
                        $data['buttons'][$item->guard_name][] = $item1->guard_name;
                    }
                });
            });

            return self::response($data);
        }

        $resHasPermissions = $roleHasPermissionsDep->getByRoleId($resUser->role_id);
        $resPermissions = $permissionsDep->getPagePermission($resHasPermissions->pluck('permission_id'));

        $data['keys'] = $resPermissions->map(function ($item) {
            return $item->guard_name;
        });

        $resButtonPermissions = $permissionsDep->getButtonPermissions($resHasPermissions->pluck('permission_id'));
        $data['buttons'] = [];
        $resPermissions->each(function ($item) use ($permissionsDep, &$data, $resButtonPermissions) {
            $resButtonPermissions->each(function ($item1) use ($item, &$data) {
                if ($item1->parent_id == $item->id) {
                    $data['buttons'][$item->guard_name][] = $item1->guard_name;
                }
            });
        });



        return self::response($data);
    }

    public function loginOut($request)
    {

        $userId = $request->user()->id;
        TokenModel::where('tokenable_id', $userId)->delete();
        return self::response();
    }

    public function ping($request)
    {
        UserModel::where('id', 1)->first();
        return self::response([], '可正常连接数据库');
    }

    public function forget($request)
    {

        $param = $request->input();

        if (empty($param['email'])) {
            return self::response([], '请输入邮箱', 100);
        }

        $dep = new UserDep();
        $resUser = $dep->firstByEmail($param['email']);
        if (!$resUser) {
            return self::response([], '邮箱错误', 200);
        }

        $now = time();
        $token = md5("{$param['email']}_{$now}_{$param['email']}_q2w3e4");
        try {
            $url = env("FRONT_URL");
            $link = "{$url}/#/reset?token={$token}&time={$now}&email={$param['email']}";
            Mail::to($param['email'])->send(new Forget($link));
        } catch (\Exception $err) {
            return self::response([], '邮件发送失败，请检查邮箱是否正确', 200);
        }
        return self::response();
    }

    public function reset($request)
    {

        $param = $request->input();
        if (empty($param['token'] || empty($param['time'] || empty($param['email'])))) {
            return self::response([], '', 100);
        }

        $now = time();
        if ($now - $param['time'] >= 60 * 5) {
            return self::response([], '', 100);
        }

        $token = md5("{$param['email']}_{$param['time']}_{$param['email']}_q2w3e4");
        if ($token != $param['token']) {
            return self::response([], '', 100);
        }

        $dep = new UserDep();
        $resUser = $dep->getByEmail($param['email']);
        if ($resUser->isEmpty()) {
            return self::response([], '', 100);
        }
        $newP = Str::random(5);
        $resUser->each(function($item) use($dep,$newP){
            $dep->upd($item->id, ['password' => $newP]);
            TokenModel::where('tokenable_id', $item->id)->delete();
        });

        return self::response(['password' => $newP]);
    }

    public function trade($request)
    {
        $param = $request->input();
        $dep = new TeamsDep();
        $res = $dep->first($param['team_id']);
        $date_at = date("Y-m-d H:i:s");
        if ($res['expire_at'] < $date_at) {
            $dep->upd($param['team_id'], ['is_open' => 2]);
            return self::response([], '工会到期', 100);
        }
        return self::response();
    }
}
